Skip to content

Perlinscape FX (2D) in the user_fx usermod#5587

Open
BobLoeffler68 wants to merge 13 commits into
wled:mainfrom
BobLoeffler68:pr-perlinscape-user-fx
Open

Perlinscape FX (2D) in the user_fx usermod#5587
BobLoeffler68 wants to merge 13 commits into
wled:mainfrom
BobLoeffler68:pr-perlinscape-user-fx

Conversation

@BobLoeffler68
Copy link
Copy Markdown
Contributor

@BobLoeffler68 BobLoeffler68 commented May 10, 2026

This PR adds the 2D Perlinscape effect into the new user_fx usermod instead of FX.cpp

  • a Perlin noise landscape animation
  • Created by stepko as part of Stepko Land on soulmatelights.com
  • Adapted to WLED by Bob Loeffler with additional features (and help from Claude)
  • First slider is for speed
  • Second slider is for zooming in/out (Perlin scaling)
  • Third slider is the X multiplier
  • Fourth slider is the Y multiplier
  • Fifth slider is the rotation speed (0 = do not rotate)
  • Checkbox will randomize the horizonal and vertical directions

Example videos:

80007897461__00E4D193-7401-4ED9-9F74-DBF3C8C172A7.mov

^-- Default settings and Rotation

IMG_6838.mov

^-- Using the Hult 64 palette

Untitled.1.mp4

^-- Hult 64 palette and mirrored X

Untitled.mp4

^-- Candy palette and Rotation

Summary by CodeRabbit

  • New Features
    • Added a "Perlinscape" 2D visual effect that renders procedurally generated Perlin-noise landscapes on matrix displays.
    • Supports raw RGB or palette-based output, adjustable zoom, intensity, X/Y scaling, optional continuous rotation, and per-frame animation.
    • Includes a toggle to enable periodic randomized X/Y flip/drift behavior and UI controls to tweak appearance in real time.

Review Change Stack

@softhack007 softhack007 added usermod usermod related AI Partly generated by an AI. Make sure that the contributor fully understands the code! effect labels May 10, 2026
@softhack007
Copy link
Copy Markdown
Member

@BobLoeffler68 I see "0 files changed" - is this expected?

image

@softhack007 softhack007 added the waiting for feedback addition information needed to better understand the issue label May 10, 2026
@BobLoeffler68
Copy link
Copy Markdown
Contributor Author

@BobLoeffler68 I see "0 files changed" - is this expected?

Hmmmmm... I'm not sure what is happening. I can't even compile it anymore as it says platform_wled_default doesn't exist in the [common] section of platformio.ini Something strange is happening.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

A new 2D "Perlinscape" user FX renders a Perlin-noise landscape across a 2D LED matrix with palette or raw RGB output, zoom/intensity and XY multipliers, optional rotation around the center, and optional timed random X/Y direction flips.

Changes

2D Perlinscape Effect

Layer / File(s) Summary
Effect Implementation and Metadata
usermods/user_fx/user_fx.cpp
mode_2D_perlinscape allocates per-effect scratch data (offsets, steps, previous time), advances time/offsets, optionally applies rotation and random direction flips, evaluates Perlin noise per pixel with zoom/intensity and XY multipliers, and renders via palette or raw RGB. Adds _data_FX_MODE_2D_PERLINSCAPE PROGMEM metadata.
Effect Registration
usermods/user_fx/user_fx.cpp
Registers mode_2D_perlinscape in UserFxUsermod::setup() using the new metadata string, making it available as a user FX mode.

Sequence Diagram

sequenceDiagram
  participant Caller
  participant mode_2D_perlinscape
  participant PerlinSampler
  participant MatrixRenderer
  Caller->>mode_2D_perlinscape: per-frame update (strip.now, SEGMENT)
  mode_2D_perlinscape->>PerlinSampler: sample noise at (x,y,offX,offY,zoom)
  PerlinSampler-->>mode_2D_perlinscape: noise channels (r,g,b/brightness)
  mode_2D_perlinscape->>MatrixRenderer: setPixelColorXY(x,y,color)
  MatrixRenderer-->>Caller: rendered frame
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

enhancement

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a 2D Perlinscape FX effect to the user_fx usermod. It is specific, accurate, and reflects the primary purpose of the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
usermods/user_fx/user_fx.cpp (2)

1335-1336: 💤 Low value

Consider uint_fast8_t for hot-path loop counters.

The nested per-pixel loops use byte (uint8_t). For hot-path performance, the coding guidelines suggest uint_fast8_t / uint_fast16_t for loop counters, though effect functions have diverse contributor styles.

♻️ Optional refactor
-  for (byte x = 0; x < width; x++) {
-    for (byte y = 0; y < height; y++) {
+  for (uint_fast8_t x = 0; x < width; x++) {
+    for (uint_fast8_t y = 0; y < height; y++) {

As per coding guidelines: Use uint_fast16_t / uint_fast8_t in hot-path code (per-frame/per-pixel loops).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/user_fx/user_fx.cpp` around lines 1335 - 1336, The per-pixel nested
loops use the typedef byte (uint8_t) for counters x and y which can be
suboptimal in hot-path rendering; change the loop counter types from byte to
uint_fast8_t (or uint_fast16_t if width/height can exceed 255) for the loops
that iterate over width and height (the variables x and y in the nested for
loops) to follow the coding guideline for per-frame/per-pixel hot-path
performance, ensuring any dependent uses/overloads accept the updated integer
type.

1261-1354: 💤 Low value

Add AI-generated code markers if applicable.

The PR description mentions "additional features (and help from Claude)" and the code comment references "help from Claude", but there are no // AI: / // AI: end markers in the code. If any contiguous blocks were AI-generated, please mark them per the coding guidelines.

Example format:

// AI: below section was generated by an AI
... AI-generated code ...
// AI: end

As per coding guidelines: Mark AI-generated code blocks with // AI: below section was generated by an AI / // AI: end comments.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/user_fx/user_fx.cpp` around lines 1261 - 1354, The function
mode_2D_perlinscape and its top comment reference “help from Claude”; if any
contiguous portion of this function or surrounding blocks was AI-generated, wrap
that exact contiguous block with the required markers (add a line "// AI: below
section was generated by an AI" before the block and "// AI: end" after it); if
no part of mode_2D_perlinscape or its comments was AI-generated, add a brief
single-line clarifying comment near the top (e.g., immediately above the
function comment) stating that no AI-generated code was used; locate code by the
symbol mode_2D_perlinscape and the header comment mentioning Claude to apply the
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1329-1330: Replace the standard library calls
cosf(angle)/sinf(angle) with the project's approximations: call
cos_approx(angle) to assign cosA and sin_approx(angle) to assign sinA; update
the expressions where cosA and sinA are set (look for the assignments to cosA
and sinA that currently use cosf/sinf with the variable angle) so they use
cos_approx(angle) and sin_approx(angle) respectively to comply with the WLED C++
coding guideline.
- Line 1277: The allocation is oversized because only five floats (offX, offY,
stepX, stepY, prevT) are used: update the SEGENV.allocateData call to allocate
exactly 5 * sizeof(float) bytes (remove the + width * height), and ensure no
other code in this scope relies on the removed buffer; locate the call to
SEGENV.allocateData and the subsequent accesses to offX/offY/stepX/stepY/prevT
to verify they're unchanged.

---

Nitpick comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1335-1336: The per-pixel nested loops use the typedef byte
(uint8_t) for counters x and y which can be suboptimal in hot-path rendering;
change the loop counter types from byte to uint_fast8_t (or uint_fast16_t if
width/height can exceed 255) for the loops that iterate over width and height
(the variables x and y in the nested for loops) to follow the coding guideline
for per-frame/per-pixel hot-path performance, ensuring any dependent
uses/overloads accept the updated integer type.
- Around line 1261-1354: The function mode_2D_perlinscape and its top comment
reference “help from Claude”; if any contiguous portion of this function or
surrounding blocks was AI-generated, wrap that exact contiguous block with the
required markers (add a line "// AI: below section was generated by an AI"
before the block and "// AI: end" after it); if no part of mode_2D_perlinscape
or its comments was AI-generated, add a brief single-line clarifying comment
near the top (e.g., immediately above the function comment) stating that no
AI-generated code was used; locate code by the symbol mode_2D_perlinscape and
the header comment mentioning Claude to apply the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 71a00cb6-14af-4164-b12e-ec1652c75822

📥 Commits

Reviewing files that changed from the base of the PR and between 37623ed and 8d8e107.

📒 Files selected for processing (1)
  • usermods/user_fx/user_fx.cpp

Comment thread usermods/user_fx/user_fx.cpp Outdated
Comment thread usermods/user_fx/user_fx.cpp Outdated
…- use cos_approx() and sin_approx() instead of cosf and sinf
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
usermods/user_fx/user_fx.cpp (2)

1337-1338: ⚡ Quick win

Consider using uint16_t for loop variables to support larger matrices.

The loop variables x and y are declared as byte (uint8_t), which limits them to 0-255. While typical WLED matrices are smaller, using uint16_t would future-proof the code for larger matrices and match the return types of SEG_W and SEG_H.

🔧 Proposed fix
-  for (byte x = 0; x < width; x++) {
-    for (byte y = 0; y < height; y++) {
+  for (uint16_t x = 0; x < width; x++) {
+    for (uint16_t y = 0; y < height; y++) {
       float rx = cosA * (x - cx) - sinA * (y - cy) + cx;
       float ry = sinA * (x - cx) + cosA * (y - cy) + cy;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/user_fx/user_fx.cpp` around lines 1337 - 1338, Loop indices x and y
are declared as byte (uint8_t), which restricts matrix sizes; change their types
to uint16_t in the nested loops that iterate over SEG_W and SEG_H (replace the
declarations of x and y in the for loops) so they match the larger return types
and support bigger matrices, and update any nearby usages/expressions that
assume byte to prevent implicit truncation.

1277-1277: 💤 Low value

Remove commented-out old code.

Lines 1277, 1329, and 1330 contain the old buggy code that has been fixed. These commented lines should be removed to keep the codebase clean.

🧹 Proposed cleanup
  const uint16_t width = SEG_W;
  const uint16_t height = SEG_H;
-//  if (!SEGENV.allocateData(5 * sizeof(float) + width * height)) FX_FALLBACK_STATIC;
  if (!SEGENV.allocateData(5 * sizeof(float))) FX_FALLBACK_STATIC;
  if (SEGMENT.check2) {
    float angle = strip.now / 5000.0f;
-//    cosA = cosf(angle);
-//    sinA = sinf(angle);
    cosA = cos_approx(angle);
    sinA = sin_approx(angle);
  }

Also applies to: 1329-1330

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/user_fx/user_fx.cpp` at line 1277, Remove the leftover commented-out
old code that calls SEGENV.allocateData and uses FX_FALLBACK_STATIC; locate
occurrences of the commented line containing "SEGENV.allocateData(5 *
sizeof(float) + width * height)) FX_FALLBACK_STATIC" and the related commented
lines and delete them so the fixed implementation remains clean and no obsolete
code is left in user_fx.cpp (search for SEGENV.allocateData and
FX_FALLBACK_STATIC to find all instances).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1337-1338: Loop indices x and y are declared as byte (uint8_t),
which restricts matrix sizes; change their types to uint16_t in the nested loops
that iterate over SEG_W and SEG_H (replace the declarations of x and y in the
for loops) so they match the larger return types and support bigger matrices,
and update any nearby usages/expressions that assume byte to prevent implicit
truncation.
- Line 1277: Remove the leftover commented-out old code that calls
SEGENV.allocateData and uses FX_FALLBACK_STATIC; locate occurrences of the
commented line containing "SEGENV.allocateData(5 * sizeof(float) + width *
height)) FX_FALLBACK_STATIC" and the related commented lines and delete them so
the fixed implementation remains clean and no obsolete code is left in
user_fx.cpp (search for SEGENV.allocateData and FX_FALLBACK_STATIC to find all
instances).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61a0d9c7-5bb0-44d1-843b-e4ee11aef293

📥 Commits

Reviewing files that changed from the base of the PR and between 8d8e107 and 0dcdbaa.

📒 Files selected for processing (1)
  • usermods/user_fx/user_fx.cpp

@blazoncek
Copy link
Copy Markdown
Contributor

This is a nice and very useful effect and I would recommend it for inclusion into core effects.

My recommendations for improvement (from Discord):

  • use Perlin color if "Default" palette is used but otherwise use selected palette (i.e. if (SEGMENT.palette == 0) ... and remove Palettes option
  • expand speed range especially towards slower side
  • reduce float use (float is painfully slow on ESP8266; i.e. don't use float for prevT, etc)

And BTW, to avoid pointer use (for a cleaner look) use references instead. I.e.

uint32_t prevT = reinterpret_cast<uint32_t&>(*SEGENV.data);
float offX  = reinterpret_cast<float&>(*(SEGENV.data + sizeof(uint32_t)));
...

Perhaps @coderabbitai can help with replacing floating point math with integer math to improve speed. Or use Claude.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

… otherwise use selected palette. Also, I expanded the speed range towards the slower side. Both requested by blazoncek.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1333-1334: The nested loops use byte-typed counters `x` and `y`
while iterating up to `width` and `height` (which are `uint16_t`), causing
overflow when a dimension >= 256; change the loop counters to a wider integer
type (e.g., `uint16_t` or `int`) wherever `for (byte x = 0; x < width; x++)` and
`for (byte y = 0; y < height; y++)` appear (in the user_fx loops) so they can
represent the full range of `width`/`height`, and update any related
variables/headers if necessary to keep types consistent.
- Around line 1295-1296: Change the prevT storage from float to uint32_t and
compute the timestamp delta as a signed integer before converting to float: keep
prevT as an unsigned 32-bit value, compute int32_t delta = (int32_t)t -
(int32_t)*prevT (or equivalent signed subtraction), then convert that delta to
float for use (e.g., float dt = (float)delta) and finally update *prevT = t;
apply this change where prevT is used (the same pattern as around lines that use
prevT elsewhere) to avoid float precision loss and wraparound artifacts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 83dc9058-f251-4fb8-8e99-6cc6a9cb960a

📥 Commits

Reviewing files that changed from the base of the PR and between 0dcdbaa and 4d1d818.

📒 Files selected for processing (1)
  • usermods/user_fx/user_fx.cpp

Comment thread usermods/user_fx/user_fx.cpp Outdated
Comment thread usermods/user_fx/user_fx.cpp Outdated
* Switched from using pointers to using references.
* Added a slider for the rotation speed (0 = no rotation), so I removed the rotation checkbox.
* Fixed a bug during rotation where the animation would "jump" because it would overflow
* Changed byte to uint16_t in for loops.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
usermods/user_fx/user_fx.cpp (1)

1287-1321: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use rollover-safe unsigned timestamp storage for prevT.

prevT is int32_t and Line 1316 does signed subtraction; this can overflow/behave incorrectly across long uptimes. Store prevT as uint32_t and compute delta via unsigned subtraction, then cast once.

🔧 Proposed fix
-  if (!SEGENV.allocateData(5 * sizeof(int32_t))) FX_FALLBACK_STATIC;
+  if (!SEGENV.allocateData(4 * sizeof(int32_t) + sizeof(uint32_t))) FX_FALLBACK_STATIC;
@@
-  int32_t &prevT = *(reinterpret_cast<int32_t*>(SEGENV.data) + 4);
+  uint32_t &prevT = *(reinterpret_cast<uint32_t*>(reinterpret_cast<int32_t*>(SEGENV.data) + 4));
@@
-    prevT = (int32_t)t;
+    prevT = t;
@@
-  int32_t dt = (int32_t)t - prevT;
+  int32_t dt = int32_t(t - prevT);
@@
-  prevT = (int32_t)t;  // store t, not strip.now
+  prevT = t;  // store t, not strip.now
#!/bin/bash
# Verify current timestamp-delta pattern in the Perlinscape effect.
rg -n -C2 'allocateData\(5 \* sizeof\(int32_t\)\)|int32_t &prevT|int32_t dt =|prevT = \(int32_t\)t' usermods/user_fx/user_fx.cpp

Based on learnings: store prior timestamps as uint32_t and compute float/int deltas from rollover-safe subtraction, not from lossy or overflow-prone representations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/user_fx/user_fx.cpp` around lines 1287 - 1321, prevT is stored/used
as int32_t which can overflow on long uptimes; change the storage to uint32_t
(the slot currently referenced as int32_t &prevT from SEGENV.data) and
write/read it as uint32_t, set it initially from (uint32_t)t, and compute dt by
unsigned subtraction: uint32_t raw_dt = (uint32_t)t - prevT; then clamp raw_dt
(e.g., if raw_dt > 1000) set dt = 0 else dt = (int32_t)raw_dt before using
offX/offY; also update the assignment at the end to prevT = (uint32_t)t. Ensure
all occurrences of prevT, the initial prevT = (int32_t)t, the dt calculation,
and prevT = (int32_t)t are updated to their unsigned equivalents.
🧹 Nitpick comments (1)
usermods/user_fx/user_fx.cpp (1)

1261-1375: ⚡ Quick win

Mark the AI-generated block with required // AI: boundary comments.

This newly added large effect block appears AI-assisted but is not wrapped with the required markers.

🔧 Proposed fix
+// AI: below section was generated by an AI
 /*
 /  Perlinscape effect - a Perlin noise Landscape
 *   Created by stepko as part of Stepko Land on soulmatelights.com
@@
 static const char _data_FX_MODE_2D_PERLINSCAPE[] PROGMEM = "Perlinscape@!,Zoom (In/Out),X multiplier,Y multiplier,Rotation speed,Random direction;;!;2;";
+// AI: end

As per coding guidelines: "Embed larger blocks of AI-generated code within // AI: below section was generated by an AI ... // AI: end comments."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@usermods/user_fx/user_fx.cpp` around lines 1261 - 1375, The large effect
function mode_2D_perlinscape appears AI-generated but lacks the required AI
boundary comments; wrap the entire AI-added block (starting at the function
declaration "static void mode_2D_perlinscape(void)" through its closing brace)
with the mandated markers — add a comment before the function like "// AI: below
section was generated by an AI" and a matching "// AI: end" comment after the
function end; ensure the markers surround only that block so symbols like
mode_2D_perlinscape, SEGENV, perlin8, and SEGMENT remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1363-1364: The multiplications computing scaled_x and scaled_y can
overflow int32_t; fix by casting operands to int64_t before the multiply chain
(e.g., cast rx256 and ry256 to int64_t), perform (int64_t)rx256 * Xmult *
scale_q8, shift the result by >>16, then static_cast back to int32_t when
assigning to scaled_x/scaled_y; update the expressions that compute scaled_x and
scaled_y accordingly to use int64_t temporaries or inline casts.

---

Duplicate comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1287-1321: prevT is stored/used as int32_t which can overflow on
long uptimes; change the storage to uint32_t (the slot currently referenced as
int32_t &prevT from SEGENV.data) and write/read it as uint32_t, set it initially
from (uint32_t)t, and compute dt by unsigned subtraction: uint32_t raw_dt =
(uint32_t)t - prevT; then clamp raw_dt (e.g., if raw_dt > 1000) set dt = 0 else
dt = (int32_t)raw_dt before using offX/offY; also update the assignment at the
end to prevT = (uint32_t)t. Ensure all occurrences of prevT, the initial prevT =
(int32_t)t, the dt calculation, and prevT = (int32_t)t are updated to their
unsigned equivalents.

---

Nitpick comments:
In `@usermods/user_fx/user_fx.cpp`:
- Around line 1261-1375: The large effect function mode_2D_perlinscape appears
AI-generated but lacks the required AI boundary comments; wrap the entire
AI-added block (starting at the function declaration "static void
mode_2D_perlinscape(void)" through its closing brace) with the mandated markers
— add a comment before the function like "// AI: below section was generated by
an AI" and a matching "// AI: end" comment after the function end; ensure the
markers surround only that block so symbols like mode_2D_perlinscape, SEGENV,
perlin8, and SEGMENT remain unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f9c9fb39-ce7a-4824-b966-d7c543942026

📥 Commits

Reviewing files that changed from the base of the PR and between b41d994 and 967cea0.

📒 Files selected for processing (1)
  • usermods/user_fx/user_fx.cpp

Comment thread usermods/user_fx/user_fx.cpp Outdated
* Fixed the speed slider and rotation slider because their middle values were pretty much the same as their lower values.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Partly generated by an AI. Make sure that the contributor fully understands the code! effect enhancement usermod usermod related waiting for feedback addition information needed to better understand the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants